Merge "sdm: Support HDR Capabilites thru DisplayFixedConfig"
diff --git a/sdm/include/core/display_interface.h b/sdm/include/core/display_interface.h
index 416e01a..1b95b91 100644
--- a/sdm/include/core/display_interface.h
+++ b/sdm/include/core/display_interface.h
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2014 - 2016, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted
 * provided that the following conditions are met:
@@ -141,6 +141,10 @@
   bool underscan = false;   //!< If display support CE underscan.
   bool secure = false;      //!< If this display is capable of handling secure content.
   bool is_cmdmode = false;  //!< If panel is command mode panel.
+  bool hdr_supported = false;  //!< if HDR is enabled
+  uint32_t max_luminance = 0;  //!< From Panel's peak luminance
+  uint32_t average_luminance = 0;  //!< From Panel's average luminance
+  uint32_t min_luminance = 0;  //!< From Panel's blackness level
 };
 
 /*! @brief This structure defines configuration for variable properties of a display device.
diff --git a/sdm/libs/core/display_base.cpp b/sdm/libs/core/display_base.cpp
index 025c583..f83055a 100644
--- a/sdm/libs/core/display_base.cpp
+++ b/sdm/libs/core/display_base.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2014 - 2016, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted
 * provided that the following conditions are met:
@@ -375,9 +375,18 @@
   return kErrorNotSupported;
 }
 
-DisplayError DisplayBase::GetConfig(DisplayConfigFixedInfo *variable_info) {
+DisplayError DisplayBase::GetConfig(DisplayConfigFixedInfo *fixed_info) {
   lock_guard<recursive_mutex> obj(recursive_mutex_);
-  variable_info->is_cmdmode = (hw_panel_info_.mode == kModeCommand);
+  fixed_info->is_cmdmode = (hw_panel_info_.mode == kModeCommand);
+
+  HWResourceInfo hw_resource_info = HWResourceInfo();
+  hw_info_intf_->GetHWResourceInfo(&hw_resource_info);
+  // hdr can be supported by display when target and panel supports HDR.
+  fixed_info->hdr_supported = (hw_resource_info.has_hdr && hw_panel_info_.hdr_enabled);
+  // Populate luminance values only if hdr will be supported on that display
+  fixed_info->max_luminance = fixed_info->hdr_supported ? hw_panel_info_.peak_luminance: 0;
+  fixed_info->average_luminance = fixed_info->hdr_supported ? hw_panel_info_.average_luminance : 0;
+  fixed_info->min_luminance = fixed_info->hdr_supported ?  hw_panel_info_.blackness_level: 0;
 
   return kErrorNone;
 }
diff --git a/sdm/libs/hwc/hwc_display.cpp b/sdm/libs/hwc/hwc_display.cpp
index e1ce108..a87706c 100644
--- a/sdm/libs/hwc/hwc_display.cpp
+++ b/sdm/libs/hwc/hwc_display.cpp
@@ -1481,6 +1481,10 @@
   return display_intf_->GetConfig(UINT32(config), display_attributes) == kErrorNone ? 0 : -1;
 }
 
+int HWCDisplay::GetDisplayFixedConfig(DisplayConfigFixedInfo *fixed_info) {
+  return display_intf_->GetConfig(fixed_info) == kErrorNone ? 0 : -1;
+}
+
 // TODO(user): HWC needs to know updating for dyn_fps, cpu hint features,
 // once the features are moved to SDM, the two functions below can be removed.
 uint32_t HWCDisplay::GetUpdatingLayersCount(uint32_t app_layer_count) {
diff --git a/sdm/libs/hwc/hwc_display.h b/sdm/libs/hwc/hwc_display.h
index b32cf93..aa50c20 100644
--- a/sdm/libs/hwc/hwc_display.h
+++ b/sdm/libs/hwc/hwc_display.h
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2014 - 2016, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted
 * provided that the following conditions are met:
@@ -129,6 +129,7 @@
   virtual int GetDisplayConfigCount(uint32_t *count);
   virtual int GetDisplayAttributesForConfig(int config,
                                             DisplayConfigVariableInfo *display_attributes);
+  virtual int GetDisplayFixedConfig(DisplayConfigFixedInfo *fixed_info);
 
   int SetPanelBrightness(int level);
   int GetPanelBrightness(int *level);
diff --git a/sdm/libs/hwc/hwc_session.cpp b/sdm/libs/hwc/hwc_session.cpp
index 408f212..cac8a8f 100644
--- a/sdm/libs/hwc/hwc_session.cpp
+++ b/sdm/libs/hwc/hwc_session.cpp
@@ -1192,19 +1192,46 @@
 
 android::status_t HWCSession::GetHdrCapabilities(const android::Parcel *input_parcel,
                                                  android::Parcel *output_parcel) {
-  // TODO(akumarkr): Get values from display intf
-  // uint32_t dpy = UINT32(input_parcel->readInt32());
-  std::vector<int32_t> supported_hdr_types;
+  uint32_t display_id = UINT32(input_parcel->readInt32());
+  if (display_id >= HWC_NUM_DISPLAY_TYPES) {
+    DLOGE("Invalid display id = %d", display_id);
+    return -EINVAL;
+  }
+
+  if (hwc_display_[display_id] == NULL) {
+    DLOGW("Display = %d not initialized", display_id);
+    return -EINVAL;
+  }
+
+  DisplayConfigFixedInfo fixed_info = {};
+  int ret = hwc_display_[display_id]->GetDisplayFixedConfig(&fixed_info);
+  if (ret) {
+    DLOGE("Failed");
+    return ret;
+  }
+
+  if (!fixed_info.hdr_supported) {
+    DLOGI("HDR is not supported");
+    return 0;
+  }
+
+  std::vector<int32_t> supported_hdr_types = {};
+  // Only HDR10 supported now, in future add other supported HDR formats(HLG, DolbyVision)
   supported_hdr_types.push_back(HAL_HDR_HDR10);
-  float max_luminance = 500.0;
-  float max_average_luminance = 200.0;
-  float min_luminance = 0.5;
+
+  static const float kLuminanceFactor = 10000.0;
+  // luminance is expressed in the unit of 0.0001 cd/m2, convert it to 1cd/m2.
+  float max_luminance = FLOAT(fixed_info.max_luminance)/kLuminanceFactor;
+  float max_average_luminance = FLOAT(fixed_info.average_luminance)/kLuminanceFactor;
+  float min_luminance = FLOAT(fixed_info.min_luminance)/kLuminanceFactor;
+
   if (output_parcel != nullptr) {
     output_parcel->writeInt32Vector(supported_hdr_types);
     output_parcel->writeFloat(max_luminance);
     output_parcel->writeFloat(max_average_luminance);
     output_parcel->writeFloat(min_luminance);
   }
+
   return 0;
 }
 
diff --git a/sdm/libs/hwc2/hwc_display.cpp b/sdm/libs/hwc2/hwc_display.cpp
index 08b1aaa..3b0015d 100644
--- a/sdm/libs/hwc2/hwc_display.cpp
+++ b/sdm/libs/hwc2/hwc_display.cpp
@@ -860,6 +860,33 @@
   return HWC2::Error::None;
 }
 
+HWC2::Error HWCDisplay::GetHdrCapabilities(uint32_t *out_num_types, int32_t *out_types,
+                                           float *out_max_luminance,
+                                           float *out_max_average_luminance,
+                                           float *out_min_luminance) {
+  DisplayConfigFixedInfo fixed_info = {};
+  display_intf_->GetConfig(&fixed_info);
+
+  if (out_types == nullptr) {
+    *out_num_types  = 0;
+    if (fixed_info.hdr_supported) {
+      // 1(now) - because we support only HDR10, change when HLG & DOLBY vision are supported
+      *out_num_types  = 1;
+    }
+  } else {
+    // Only HDR10 supported
+    out_types[0] = HAL_HDR_HDR10;
+    static const float kLuminanceFactor = 10000.0;
+    // luminance is expressed in the unit of 0.0001 cd/m2, convert it to 1cd/m2.
+    *out_max_luminance = FLOAT(fixed_info.max_luminance)/kLuminanceFactor;
+    *out_max_average_luminance = FLOAT(fixed_info.average_luminance)/kLuminanceFactor;
+    *out_min_luminance = FLOAT(fixed_info.min_luminance)/kLuminanceFactor;
+  }
+
+  return HWC2::Error::None;
+}
+
+
 HWC2::Error HWCDisplay::CommitLayerStack(void) {
   if (shutdown_pending_ || layer_set_.empty()) {
     return HWC2::Error::None;
diff --git a/sdm/libs/hwc2/hwc_display.h b/sdm/libs/hwc2/hwc_display.h
index 2221027..165e2c3 100644
--- a/sdm/libs/hwc2/hwc_display.h
+++ b/sdm/libs/hwc2/hwc_display.h
@@ -181,6 +181,10 @@
   virtual HWC2::Error GetReleaseFences(uint32_t *out_num_elements, hwc2_layer_t *out_layers,
                                        int32_t *out_fences);
   virtual HWC2::Error Present(int32_t *out_retire_fence) = 0;
+  virtual HWC2::Error GetHdrCapabilities(uint32_t *out_num_types, int32_t* out_types,
+                                         float* out_max_luminance,
+                                         float* out_max_average_luminance,
+                                         float* out_min_luminance);
 
  protected:
   enum DisplayStatus {
diff --git a/sdm/libs/hwc2/hwc_session.cpp b/sdm/libs/hwc2/hwc_session.cpp
index 79a3a37..ee4a6e7 100644
--- a/sdm/libs/hwc2/hwc_session.cpp
+++ b/sdm/libs/hwc2/hwc_session.cpp
@@ -367,8 +367,9 @@
                                   uint32_t* out_num_types, int32_t* out_types,
                                   float* out_max_luminance, float* out_max_average_luminance,
                                   float* out_min_luminance) {
-  *out_num_types = 0;
-  return HWC2_ERROR_NONE;
+  return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetHdrCapabilities,
+                                         out_num_types, out_types, out_max_luminance,
+                                         out_max_average_luminance, out_min_luminance);
 }
 
 static uint32_t GetMaxVirtualDisplayCount(hwc2_device_t *device) {