SF: Add colorTransform to DisplayInfo

Adds the colorTransform field, which defines a vendor-specific color
transform (e.g., wide gamut, sRGB, etc.) to the DisplayInfo class, and
populates it from the HWC interface.

Bug: 20853317
Change-Id: I153edc36a361407656f3eb5082b96c2da2ecbec7
diff --git a/include/ui/DisplayInfo.h b/include/ui/DisplayInfo.h
index 799944f..ad73ee7 100644
--- a/include/ui/DisplayInfo.h
+++ b/include/ui/DisplayInfo.h
@@ -36,6 +36,7 @@
     bool secure;
     nsecs_t appVsyncOffset;
     nsecs_t presentationDeadline;
+    int colorTransform;
 };
 
 /* Display orientations as defined in Surface.java and ISurfaceComposer.h. */
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 2dad005..0859149 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -336,10 +336,20 @@
     HWC_DISPLAY_HEIGHT,
     HWC_DISPLAY_DPI_X,
     HWC_DISPLAY_DPI_Y,
+    HWC_DISPLAY_COLOR_TRANSFORM,
     HWC_DISPLAY_NO_ATTRIBUTE,
 };
 #define NUM_DISPLAY_ATTRIBUTES (sizeof(DISPLAY_ATTRIBUTES) / sizeof(DISPLAY_ATTRIBUTES)[0])
 
+static const uint32_t PRE_HWC15_DISPLAY_ATTRIBUTES[] = {
+    HWC_DISPLAY_VSYNC_PERIOD,
+    HWC_DISPLAY_WIDTH,
+    HWC_DISPLAY_HEIGHT,
+    HWC_DISPLAY_DPI_X,
+    HWC_DISPLAY_DPI_Y,
+    HWC_DISPLAY_NO_ATTRIBUTE,
+};
+
 status_t HWComposer::queryDisplayProperties(int disp) {
 
     LOG_ALWAYS_FATAL_IF(!mHwc || !hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1));
@@ -362,6 +372,12 @@
     for (size_t c = 0; c < numConfigs; ++c) {
         err = mHwc->getDisplayAttributes(mHwc, disp, configs[c],
                 DISPLAY_ATTRIBUTES, values);
+        // If this is a pre-1.5 HWC, it may not know about color transform, so
+        // try again with a smaller set of attributes
+        if (err != NO_ERROR) {
+            err = mHwc->getDisplayAttributes(mHwc, disp, configs[c],
+                    PRE_HWC15_DISPLAY_ATTRIBUTES, values);
+        }
         if (err != NO_ERROR) {
             // we can't get this display's info. turn it off.
             mDisplayData[disp].connected = false;
@@ -386,6 +402,9 @@
                 case HWC_DISPLAY_DPI_Y:
                     config.ydpi = values[i] / 1000.0f;
                     break;
+                case HWC_DISPLAY_COLOR_TRANSFORM:
+                    config.colorTransform = values[i];
+                    break;
                 default:
                     ALOG_ASSERT(false, "unknown display attribute[%zu] %#x",
                             i, DISPLAY_ATTRIBUTES[i]);
@@ -1162,9 +1181,11 @@
             result.appendFormat("  Display[%zd] configurations (* current):\n", i);
             for (size_t c = 0; c < disp.configs.size(); ++c) {
                 const DisplayConfig& config(disp.configs[c]);
-                result.appendFormat("    %s%zd: %ux%u, xdpi=%f, ydpi=%f, refresh=%" PRId64 "\n",
-                        c == disp.currentConfig ? "* " : "", c, config.width, config.height,
-                        config.xdpi, config.ydpi, config.refresh);
+                result.appendFormat("    %s%zd: %ux%u, xdpi=%f, ydpi=%f"
+                        ", refresh=%" PRId64 ", colorTransform=%d\n",
+                        c == disp.currentConfig ? "* " : "", c,
+                        config.width, config.height, config.xdpi, config.ydpi,
+                        config.refresh, config.colorTransform);
             }
 
             if (disp.list) {
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index cc98b4c..5e0b3d8 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -257,6 +257,7 @@
         float xdpi;
         float ydpi;
         nsecs_t refresh;
+        int colorTransform;
     };
 
     // Query display parameters.  Pass in a display index (e.g.
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 01ffac2..fdc3650 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -632,6 +632,7 @@
         info.ydpi = ydpi;
         info.fps = float(1e9 / hwConfig.refresh);
         info.appVsyncOffset = VSYNC_EVENT_PHASE_OFFSET_NS;
+        info.colorTransform = hwConfig.colorTransform;
 
         // This is how far in advance a buffer must be queued for
         // presentation at a given time.  If you want a buffer to appear