Add hdr attributes to setSurfaceAttr

Keep original copies of hdr metadata to return to the user if requested.
Scale integer values prior to sending to system.

Test: --deqp-case=dEQP-EGL.functional.hdr_color.*
Bug: 72491459, 72828483

Change-Id: I86ed35cf96d740ac230cc10acde322acbeffe847
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index 26ae13d..b00602c 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -479,8 +479,8 @@
 // Return true if we stripped any EGL_GL_COLORSPACE_KHR or HDR metadata attributes.
 // Protect devices from attributes they don't recognize that are  managed by Android
 static EGLBoolean stripAttributes(egl_display_ptr dp, const EGLint* attrib_list,
-                                           EGLint format,
-                                           std::vector<EGLint>& stripped_attrib_list) {
+                                  EGLint format,
+                                  std::vector<EGLint>& stripped_attrib_list) {
     std::vector<EGLint> allowedColorSpaces;
     switch (format) {
         case HAL_PIXEL_FORMAT_RGBA_8888:
@@ -712,7 +712,8 @@
         cta8613 |= s->setCta8613Attribute(attr[0], attr[1]);
     }
     if (smpte2086) {
-        int err = native_window_set_buffers_smpte2086_metadata(window, s->getSmpte2086Metadata());
+        android_smpte2086_metadata metadata = s->getSmpte2086Metadata();
+        int err = native_window_set_buffers_smpte2086_metadata(window, &metadata);
         if (err != 0) {
             ALOGE("error setting native window smpte2086 metadata: %s (%d)",
                   strerror(-err), err);
@@ -721,7 +722,8 @@
         }
     }
     if (cta8613) {
-        int err = native_window_set_buffers_cta861_3_metadata(window, s->getCta8613Metadata());
+        android_cta861_3_metadata metadata = s->getCta8613Metadata();
+        int err = native_window_set_buffers_cta861_3_metadata(window, &metadata);
         if (err != 0) {
             ALOGE("error setting native window CTS 861.3 metadata: %s (%d)",
                   strerror(-err), err);
@@ -1578,7 +1580,11 @@
         return (err == 0) ? EGL_TRUE : setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
     }
 
-    if (s->cnx->egl.eglSurfaceAttrib) {
+    if (s->setSmpte2086Attribute(attribute, value)) {
+        return EGL_TRUE;
+    } else if (s->setCta8613Attribute(attribute, value)) {
+        return EGL_TRUE;
+    } else if (s->cnx->egl.eglSurfaceAttrib) {
         return s->cnx->egl.eglSurfaceAttrib(
                 dp->disp.dpy, s->surface, attribute, value);
     }
diff --git a/opengl/libs/EGL/egl_object.cpp b/opengl/libs/EGL/egl_object.cpp
index 13b94b6..b68fd61 100644
--- a/opengl/libs/EGL/egl_object.cpp
+++ b/opengl/libs/EGL/egl_object.cpp
@@ -64,8 +64,8 @@
         cnx(cnx),
         connected(true),
         colorSpace(colorSpace),
-        smpte2086_metadata({}),
-        cta861_3_metadata({}) {
+        egl_smpte2086_metadata({}),
+        egl_cta861_3_metadata({}) {
     if (win) {
         win->incStrong(this);
     }
@@ -90,36 +90,35 @@
 
 EGLBoolean egl_surface_t::setSmpte2086Attribute(EGLint attribute, EGLint value) {
     switch (attribute) {
-            break;
         case EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT:
-            smpte2086_metadata.displayPrimaryRed.x = value;
+            egl_smpte2086_metadata.displayPrimaryRed.x = value;
             return EGL_TRUE;
         case EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT:
-            smpte2086_metadata.displayPrimaryRed.y = value;
+            egl_smpte2086_metadata.displayPrimaryRed.y = value;
             return EGL_TRUE;
         case EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT:
-            smpte2086_metadata.displayPrimaryGreen.x = value;
+            egl_smpte2086_metadata.displayPrimaryGreen.x = value;
             return EGL_TRUE;
         case EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT:
-            smpte2086_metadata.displayPrimaryGreen.y = value;
+            egl_smpte2086_metadata.displayPrimaryGreen.y = value;
             return EGL_TRUE;
         case EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT:
-            smpte2086_metadata.displayPrimaryBlue.x = value;
+            egl_smpte2086_metadata.displayPrimaryBlue.x = value;
             return EGL_TRUE;
         case EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT:
-            smpte2086_metadata.displayPrimaryBlue.y = value;
+            egl_smpte2086_metadata.displayPrimaryBlue.y = value;
             return EGL_TRUE;
         case EGL_SMPTE2086_WHITE_POINT_X_EXT:
-            smpte2086_metadata.whitePoint.x = value;
+            egl_smpte2086_metadata.whitePoint.x = value;
             return EGL_TRUE;
         case EGL_SMPTE2086_WHITE_POINT_Y_EXT:
-            smpte2086_metadata.whitePoint.y = value;
+            egl_smpte2086_metadata.whitePoint.y = value;
             return EGL_TRUE;
         case EGL_SMPTE2086_MAX_LUMINANCE_EXT:
-            smpte2086_metadata.maxLuminance = value;
+            egl_smpte2086_metadata.maxLuminance = value;
             return EGL_TRUE;
         case EGL_SMPTE2086_MIN_LUMINANCE_EXT:
-            smpte2086_metadata.minLuminance = value;
+            egl_smpte2086_metadata.minLuminance = value;
             return EGL_TRUE;
     }
     return EGL_FALSE;
@@ -128,15 +127,39 @@
 EGLBoolean egl_surface_t::setCta8613Attribute(EGLint attribute, EGLint value) {
     switch (attribute) {
         case EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT:
-            cta861_3_metadata.maxContentLightLevel = value;
+            egl_cta861_3_metadata.maxContentLightLevel = value;
             return EGL_TRUE;
         case EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT:
-            cta861_3_metadata.maxFrameAverageLightLevel = value;
+            egl_cta861_3_metadata.maxFrameAverageLightLevel = value;
             return EGL_TRUE;
     }
     return EGL_FALSE;
 }
 
+const android_smpte2086_metadata egl_surface_t::getSmpte2086Metadata() {
+    android_smpte2086_metadata metadata;
+    metadata.displayPrimaryRed.x = static_cast<float>(egl_smpte2086_metadata.displayPrimaryRed.x) / EGL_METADATA_SCALING_EXT;
+    metadata.displayPrimaryRed.y = static_cast<float>(egl_smpte2086_metadata.displayPrimaryRed.y) / EGL_METADATA_SCALING_EXT;
+    metadata.displayPrimaryGreen.x = static_cast<float>(egl_smpte2086_metadata.displayPrimaryGreen.x) / EGL_METADATA_SCALING_EXT;
+    metadata.displayPrimaryGreen.y = static_cast<float>(egl_smpte2086_metadata.displayPrimaryGreen.y) / EGL_METADATA_SCALING_EXT;
+    metadata.displayPrimaryBlue.x = static_cast<float>(egl_smpte2086_metadata.displayPrimaryBlue.x) / EGL_METADATA_SCALING_EXT;
+    metadata.displayPrimaryBlue.y = static_cast<float>(egl_smpte2086_metadata.displayPrimaryBlue.y) / EGL_METADATA_SCALING_EXT;
+    metadata.whitePoint.x = static_cast<float>(egl_smpte2086_metadata.whitePoint.x) / EGL_METADATA_SCALING_EXT;
+    metadata.whitePoint.y = static_cast<float>(egl_smpte2086_metadata.whitePoint.y) / EGL_METADATA_SCALING_EXT;
+    metadata.maxLuminance = static_cast<float>(egl_smpte2086_metadata.maxLuminance) / EGL_METADATA_SCALING_EXT;
+    metadata.minLuminance = static_cast<float>(egl_smpte2086_metadata.minLuminance) / EGL_METADATA_SCALING_EXT;
+
+    return metadata;
+}
+
+const android_cta861_3_metadata egl_surface_t::getCta8613Metadata() {
+    android_cta861_3_metadata metadata;
+    metadata.maxContentLightLevel = static_cast<float>(egl_cta861_3_metadata.maxContentLightLevel) / EGL_METADATA_SCALING_EXT;
+    metadata.maxFrameAverageLightLevel = static_cast<float>(egl_cta861_3_metadata.maxFrameAverageLightLevel) / EGL_METADATA_SCALING_EXT;
+    return metadata;
+}
+
+
 EGLBoolean egl_surface_t::getColorSpaceAttribute(EGLint attribute, EGLint* value) const {
     if (attribute == EGL_GL_COLORSPACE_KHR) {
         *value = colorSpace;
@@ -148,43 +171,43 @@
 EGLBoolean egl_surface_t::getSmpte2086Attribute(EGLint attribute, EGLint *value) const {
     switch (attribute) {
         case EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT:
-            *value = *reinterpret_cast<const int*>(&smpte2086_metadata.displayPrimaryRed.x);
+            *value = egl_smpte2086_metadata.displayPrimaryRed.x;
             return EGL_TRUE;
             break;
         case EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT:
-            *value = *reinterpret_cast<const int*>(&smpte2086_metadata.displayPrimaryRed.y);
+            *value = egl_smpte2086_metadata.displayPrimaryRed.y;
             return EGL_TRUE;
             break;
         case EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT:
-            *value = *reinterpret_cast<const int*>(&smpte2086_metadata.displayPrimaryGreen.x);
+            *value = egl_smpte2086_metadata.displayPrimaryGreen.x;
             return EGL_TRUE;
             break;
         case EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT:
-            *value = *reinterpret_cast<const int*>(&smpte2086_metadata.displayPrimaryGreen.y);
+            *value = egl_smpte2086_metadata.displayPrimaryGreen.y;
             return EGL_TRUE;
             break;
         case EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT:
-            *value = *reinterpret_cast<const int*>(&smpte2086_metadata.displayPrimaryBlue.x);
+            *value = egl_smpte2086_metadata.displayPrimaryBlue.x;
             return EGL_TRUE;
             break;
         case EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT:
-            *value = *reinterpret_cast<const int*>(&smpte2086_metadata.displayPrimaryBlue.y);
+            *value = egl_smpte2086_metadata.displayPrimaryBlue.y;
             return EGL_TRUE;
             break;
         case EGL_SMPTE2086_WHITE_POINT_X_EXT:
-            *value = *reinterpret_cast<const int*>(&smpte2086_metadata.whitePoint.x);
+            *value = egl_smpte2086_metadata.whitePoint.x;
             return EGL_TRUE;
             break;
         case EGL_SMPTE2086_WHITE_POINT_Y_EXT:
-            *value = *reinterpret_cast<const int*>(&smpte2086_metadata.whitePoint.y);
+            *value = egl_smpte2086_metadata.whitePoint.y;
             return EGL_TRUE;
             break;
         case EGL_SMPTE2086_MAX_LUMINANCE_EXT:
-            *value = *reinterpret_cast<const int*>(&smpte2086_metadata.maxLuminance);
+            *value = egl_smpte2086_metadata.maxLuminance;
             return EGL_TRUE;
             break;
         case EGL_SMPTE2086_MIN_LUMINANCE_EXT:
-            *value = *reinterpret_cast<const int*>(&smpte2086_metadata.minLuminance);
+            *value = egl_smpte2086_metadata.minLuminance;
             return EGL_TRUE;
             break;
     }
@@ -194,11 +217,11 @@
 EGLBoolean egl_surface_t::getCta8613Attribute(EGLint attribute, EGLint *value) const {
     switch (attribute) {
         case EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT:
-            *value = *reinterpret_cast<const int*>(&cta861_3_metadata.maxContentLightLevel);
+            *value = egl_cta861_3_metadata.maxContentLightLevel;
             return EGL_TRUE;
             break;
         case EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT:
-            *value = *reinterpret_cast<const int*>(&cta861_3_metadata.maxFrameAverageLightLevel);
+            *value = egl_cta861_3_metadata.maxFrameAverageLightLevel;
             return EGL_TRUE;
             break;
     }
diff --git a/opengl/libs/EGL/egl_object.h b/opengl/libs/EGL/egl_object.h
index a9020a1..bda91bb 100644
--- a/opengl/libs/EGL/egl_object.h
+++ b/opengl/libs/EGL/egl_object.h
@@ -142,8 +142,8 @@
     EGLBoolean getColorSpaceAttribute(EGLint attribute, EGLint* value) const;
     EGLBoolean getSmpte2086Attribute(EGLint attribute, EGLint* value) const;
     EGLBoolean getCta8613Attribute(EGLint attribute, EGLint* value) const;
-    const android_smpte2086_metadata* getSmpte2086Metadata() const { return &smpte2086_metadata; }
-    const android_cta861_3_metadata* getCta8613Metadata() const { return &cta861_3_metadata; }
+    const android_smpte2086_metadata getSmpte2086Metadata();
+    const android_cta861_3_metadata getCta8613Metadata();
 
     // Try to keep the order of these fields and size unchanged. It's not public API, but
     // it's not hard to imagine native games accessing them.
@@ -157,8 +157,27 @@
     bool connected;
     void disconnect();
     EGLint colorSpace;
-    android_smpte2086_metadata smpte2086_metadata;
-    android_cta861_3_metadata cta861_3_metadata;
+
+    struct egl_xy_color {
+        EGLint x;
+        EGLint y;
+    };
+
+    struct egl_smpte2086_metadata {
+        struct egl_xy_color displayPrimaryRed;
+        struct egl_xy_color displayPrimaryGreen;
+        struct egl_xy_color displayPrimaryBlue;
+        struct egl_xy_color whitePoint;
+        EGLint maxLuminance;
+        EGLint minLuminance;
+    };
+
+    struct egl_cta861_3_metadata {
+        EGLint maxContentLightLevel;
+        EGLint maxFrameAverageLightLevel;
+    };
+    egl_smpte2086_metadata egl_smpte2086_metadata;
+    egl_cta861_3_metadata egl_cta861_3_metadata;
 };
 
 class egl_context_t: public egl_object_t {