Merge "sdm: Fix memory leaks." into dev-1.0
diff --git a/libgralloc/gralloc_priv.h b/libgralloc/gralloc_priv.h
old mode 100755
new mode 100644
index 1438546..1370eac
--- a/libgralloc/gralloc_priv.h
+++ b/libgralloc/gralloc_priv.h
@@ -86,6 +86,8 @@
 #define GRALLOC_MODULE_PERFORM_GET_MAP_SECURE_BUFFER_INFO 8
 #define GRALLOC_MODULE_PERFORM_GET_UBWC_FLAG 9
 #define GRALLOC_MODULE_PERFORM_GET_RGB_DATA_ADDRESS 10
+#define GRALLOC_MODULE_PERFORM_GET_IGC 11
+#define GRALLOC_MODULE_PERFORM_SET_IGC 12
 
 /* OEM specific HAL formats */
 
@@ -148,6 +150,10 @@
 #define HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR   0x93DC
 #define HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR   0x93DD
 
+/* possible values for inverse gamma correction */
+#define HAL_IGC_NOT_SPECIFIED     0
+#define HAL_IGC_s_RGB             1
+
 /* possible formats for 3D content*/
 enum {
     HAL_NO_3D                      = 0x0,
diff --git a/libgralloc/mapper.cpp b/libgralloc/mapper.cpp
index a5d3e69..8d8532b 100644
--- a/libgralloc/mapper.cpp
+++ b/libgralloc/mapper.cpp
@@ -453,6 +453,33 @@
                 }
             } break;
 
+        case GRALLOC_MODULE_PERFORM_GET_IGC:
+            {
+                private_handle_t* hnd = va_arg(args, private_handle_t*);
+                uint32_t *igc = va_arg(args, uint32_t *);
+                if (!private_handle_t::validate(hnd) && igc) {
+                    MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
+                    if (metadata && (metadata->operation & SET_IGC)) {
+                        *igc = metadata->igc;
+                        res = 0;
+                    }
+                }
+            } break;
+
+        case GRALLOC_MODULE_PERFORM_SET_IGC:
+            {
+                private_handle_t* hnd = va_arg(args, private_handle_t*);
+                uint32_t igc = va_arg(args, uint32_t);
+                if (!private_handle_t::validate(hnd)) {
+                    MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
+                    if (metadata) {
+                        metadata->igc = (IGC_t) igc;
+                        metadata->operation |= SET_IGC;
+                        res = 0;
+                    }
+                }
+            } break;
+
         default:
             break;
     }
diff --git a/libqdutils/qdMetaData.cpp b/libqdutils/qdMetaData.cpp
index 952952d..a66704e 100644
--- a/libqdutils/qdMetaData.cpp
+++ b/libqdutils/qdMetaData.cpp
@@ -99,6 +99,9 @@
         case LINEAR_FORMAT:
             data->linearFormat = *((uint32_t *)param);
             break;
+        case SET_IGC:
+            data->igc = *((IGC_t *)param);
+            break;
         default:
             ALOGE("Unknown paramType %d", paramType);
             break;
diff --git a/libqdutils/qdMetaData.h b/libqdutils/qdMetaData.h
index 7688444..532a6d8 100644
--- a/libqdutils/qdMetaData.h
+++ b/libqdutils/qdMetaData.h
@@ -42,6 +42,11 @@
     ITU_R_709,
 };
 
+enum IGC_t {
+    IGC_NotSpecified,
+    IGC_sRGB,
+};
+
 struct HSICData_t {
     int32_t hue;
     float   saturation;
@@ -79,6 +84,7 @@
     int64_t timestamp;
     uint32_t refreshrate;
     enum ColorSpace_t colorSpace;
+    enum IGC_t igc;
      /* Gralloc sets PRIV_SECURE_BUFFER flag to inform that the buffers are from
       * ION_SECURE. which should not be mapped. However, for GPU post proc
       * feature, GFX needs to map this buffer, in the client context and in SF
@@ -107,6 +113,7 @@
     MAP_SECURE_BUFFER = 0x400,
     S3D_FORMAT = 0x800,
     LINEAR_FORMAT = 0x1000,
+    SET_IGC = 0x2000,
 };
 
 struct private_handle_t;
diff --git a/sdm/include/core/layer_stack.h b/sdm/include/core/layer_stack.h
index b2a8210..2a79770 100644
--- a/sdm/include/core/layer_stack.h
+++ b/sdm/include/core/layer_stack.h
@@ -93,10 +93,23 @@
                             //!< Blit target layers shall be after GPU target layer in layer stack.
 };
 
-enum LayerColorSpace {
-  kLimitedRange601,       //!< 601 limited range color space
-  kFullRange601,          //!< 601 full range color space
-  kLimitedRange709,       //!< 709 limited range color space
+/*! @brief This enum represents display layer color space conversion (CSC) matrix types.
+
+  @sa Layer
+*/
+enum LayerCSC {
+  kCSCLimitedRange601,    //!< 601 limited range color space.
+  kCSCFullRange601,       //!< 601 full range color space.
+  kCSCLimitedRange709,    //!< 709 limited range color space.
+};
+
+/*! @brief This enum represents display layer inverse gamma correction (IGC) types.
+
+  @sa Layer
+*/
+enum LayerIGC {
+  kIGCNotSpecified,       //!< IGC is not specified.
+  kIGCsRGB,               //!< sRGB IGC type.
 };
 
 /*! @brief This structure defines rotation and flip values for a display layer.
@@ -260,15 +273,17 @@
                                                    //!<    }
                                                    //!<    pixel.a = pixel.a * planeAlpha
 
-  LayerFlags flags;                                //!< Flags associated with this layer.
-
   uint32_t frame_rate = 0;                         //!< Rate at which frames are being updated for
                                                    //!< this layer.
 
-  LayerColorSpace color_space = kLimitedRange601;  //!< Color Space of the layer
+  LayerCSC csc = kCSCLimitedRange601;              //!< Color Space of the layer.
+
+  LayerIGC igc = kIGCNotSpecified;                 //!< IGC that will be applied on this layer.
 
   uint32_t solid_fill_color = 0;                   //!< Solid color used to fill the layer when
                                                    //!< no content is associated with the layer.
+
+  LayerFlags flags;                                //!< Flags associated with this layer.
 };
 
 /*! @brief This structure defines a layer stack that contains layers which need to be composed and
diff --git a/sdm/include/private/hw_info_types.h b/sdm/include/private/hw_info_types.h
index 37d1f17..6aa7eab 100644
--- a/sdm/include/private/hw_info_types.h
+++ b/sdm/include/private/hw_info_types.h
@@ -228,14 +228,14 @@
   uint8_t horizontal_decimation = 0;
   uint8_t vertical_decimation = 0;
   ScaleData scale_data;
-  bool valid = false;
   uint32_t z_order = 0;
+  bool set_igc = false;
+  bool valid = false;
 
   void Reset() { *this = HWPipeInfo(); }
 };
 
 struct HWLayerConfig {
-  bool use_non_dma_pipe = false;  // set by client
   HWPipeInfo left_pipe;           // pipe for left side of output
   HWPipeInfo right_pipe;          // pipe for right side of output
   HWRotatorSession hw_rotator_session;
diff --git a/sdm/include/private/resource_interface.h b/sdm/include/private/resource_interface.h
index bc1a37d..260bcf4 100644
--- a/sdm/include/private/resource_interface.h
+++ b/sdm/include/private/resource_interface.h
@@ -45,7 +45,8 @@
   virtual void Purge(Handle display_ctx) = 0;
   virtual DisplayError SetMaxMixerStages(Handle display_ctx, uint32_t max_mixer_stages) = 0;
   virtual DisplayError ValidateScaling(const LayerRect &crop, const LayerRect &dst,
-                                       bool rotate90, bool ubwc_tiled) = 0;
+                                       bool rotate90, bool ubwc_tiled,
+                                       bool use_rotator_downscale) = 0;
   virtual DisplayError ValidateCursorConfig(Handle display_ctx, const Layer &layer,
                                             bool is_top) = 0;
   virtual DisplayError ValidateCursorPosition(Handle display_ctx, HWLayers *hw_layers,
diff --git a/sdm/libs/core/comp_manager.cpp b/sdm/libs/core/comp_manager.cpp
index 9e1b277..2c64875 100644
--- a/sdm/libs/core/comp_manager.cpp
+++ b/sdm/libs/core/comp_manager.cpp
@@ -393,7 +393,8 @@
 
 DisplayError CompManager::ValidateScaling(const LayerRect &crop, const LayerRect &dst,
                                           bool rotate90) {
-  return resource_intf_->ValidateScaling(crop, dst, rotate90, Debug::IsUbwcTiledFrameBuffer());
+  return resource_intf_->ValidateScaling(crop, dst, rotate90, Debug::IsUbwcTiledFrameBuffer(),
+                                         true /* use_rotator_downscale */);
 }
 
 DisplayError CompManager::ValidateCursorPosition(Handle display_ctx, HWLayers *hw_layers,
diff --git a/sdm/libs/core/fb/hw_device.cpp b/sdm/libs/core/fb/hw_device.cpp
index d5cde24..273786b 100644
--- a/sdm/libs/core/fb/hw_device.cpp
+++ b/sdm/libs/core/fb/hw_device.cpp
@@ -224,7 +224,10 @@
         SetRect(pipe_info->src_roi, &mdp_layer.src_rect);
         SetRect(pipe_info->dst_roi, &mdp_layer.dst_rect);
         SetMDPFlags(layer, is_rotator_used, is_cursor_pipe_used, &mdp_layer.flags);
-        SetColorSpace(layer.color_space, &mdp_layer.color_space);
+        SetCSC(layer.csc, &mdp_layer.color_space);
+        if (pipe_info->set_igc) {
+          SetIGC(layer, mdp_layer_count);
+        }
         mdp_layer.bg_color = layer.solid_fill_color;
 
         if (pipe_info->scale_data.enable_pixel_ext) {
@@ -874,6 +877,8 @@
   memset(&mdp_in_layers_, 0, sizeof(mdp_in_layers_));
   memset(&mdp_out_layer_, 0, sizeof(mdp_out_layer_));
   memset(&scale_data_, 0, sizeof(scale_data_));
+  memset(&pp_params_, 0, sizeof(pp_params_));
+  memset(&igc_lut_data_, 0, sizeof(igc_lut_data_));
 
   for (uint32_t i = 0; i < kMaxSDELayers * 2; i++) {
     mdp_in_layers_[i].buffer.fence = -1;
@@ -917,14 +922,38 @@
   }
 }
 
-void HWDevice::SetColorSpace(LayerColorSpace source, mdp_color_space *color_space) {
+void HWDevice::SetCSC(LayerCSC source, mdp_color_space *color_space) {
   switch (source) {
-  case kLimitedRange601:    *color_space = MDP_CSC_ITU_R_601;      break;
-  case kFullRange601:       *color_space = MDP_CSC_ITU_R_601_FR;   break;
-  case kLimitedRange709:    *color_space = MDP_CSC_ITU_R_709;      break;
+  case kCSCLimitedRange601:    *color_space = MDP_CSC_ITU_R_601;      break;
+  case kCSCFullRange601:       *color_space = MDP_CSC_ITU_R_601_FR;   break;
+  case kCSCLimitedRange709:    *color_space = MDP_CSC_ITU_R_709;      break;
   }
 }
 
+void HWDevice::SetIGC(const Layer &layer, uint32_t index) {
+  mdp_input_layer &mdp_layer = mdp_in_layers_[index];
+  mdp_overlay_pp_params &pp_params = pp_params_[index];
+  mdp_igc_lut_data_v1_7 &igc_lut_data = igc_lut_data_[index];
+
+  switch (layer.igc) {
+  case kIGCsRGB:
+    igc_lut_data.table_fmt = mdp_igc_srgb;
+    pp_params.igc_cfg.ops = MDP_PP_OPS_WRITE | MDP_PP_OPS_ENABLE;
+    break;
+
+  default:
+    pp_params.igc_cfg.ops = MDP_PP_OPS_DISABLE;
+    break;
+  }
+
+  pp_params.config_ops = MDP_OVERLAY_PP_IGC_CFG;
+  pp_params.igc_cfg.version = mdp_igc_v1_7;
+  pp_params.igc_cfg.cfg_payload = &igc_lut_data;
+
+  mdp_layer.pp_info = &pp_params;
+  mdp_layer.flags |= MDP_LAYER_PP;
+}
+
 DisplayError HWDevice::SetCursorPosition(HWLayers *hw_layers, int x, int y) {
   DTRACE_SCOPED();
 
diff --git a/sdm/libs/core/fb/hw_device.h b/sdm/libs/core/fb/hw_device.h
index 09fddc2..b4205e0 100644
--- a/sdm/libs/core/fb/hw_device.h
+++ b/sdm/libs/core/fb/hw_device.h
@@ -108,7 +108,8 @@
   mdp_scale_data* GetScaleDataRef(uint32_t index) { return &scale_data_[index]; }
   void SetHWScaleData(const ScaleData &scale, uint32_t index);
   void ResetDisplayParams();
-  void SetColorSpace(LayerColorSpace source, mdp_color_space *color_space);
+  void SetCSC(LayerCSC source, mdp_color_space *color_space);
+  void SetIGC(const Layer &layer, uint32_t index);
 
   bool EnableHotPlugDetection(int enable);
   ssize_t SysFsWrite(char* file_node, char* value, ssize_t length);
@@ -127,6 +128,8 @@
   mdp_layer_commit mdp_disp_commit_;
   mdp_input_layer mdp_in_layers_[kMaxSDELayers * 2];   // split panel (left + right)
   mdp_scale_data scale_data_[kMaxSDELayers * 2];
+  mdp_overlay_pp_params pp_params_[kMaxSDELayers * 2];
+  mdp_igc_lut_data_v1_7 igc_lut_data_[kMaxSDELayers * 2];
   mdp_output_layer mdp_out_layer_;
   const char *device_name_;
   bool synchronous_commit_;
diff --git a/sdm/libs/core/resource_default.cpp b/sdm/libs/core/resource_default.cpp
index 8c67b82..6efe078 100644
--- a/sdm/libs/core/resource_default.cpp
+++ b/sdm/libs/core/resource_default.cpp
@@ -546,7 +546,8 @@
   }
 
   bool ubwc_tiled = IsUBWCFormat(layer.input_buffer->format);
-  error = ValidateScaling(src_rect, dst_rect, false, ubwc_tiled);
+  error = ValidateScaling(src_rect, dst_rect, false /*rotated90 */, ubwc_tiled,
+                          false /* use_rotator_downscale */);
   if (error != kErrorNone) {
     return error;
   }
@@ -705,7 +706,8 @@
     return error;
   }
 
-  error = ValidateScaling(src_rect, dst_rect, false, ubwc_tiled);
+  error = ValidateScaling(src_rect, dst_rect, false /* rotated90 */, ubwc_tiled,
+                          false /* use_rotator_downscale */);
   if (error != kErrorNone) {
     return error;
   }
@@ -714,7 +716,8 @@
 }
 
 DisplayError ResourceDefault::ValidateScaling(const LayerRect &crop, const LayerRect &dst,
-                                         bool rotate90, bool ubwc_tiled) {
+                                              bool rotate90, bool ubwc_tiled,
+                                              bool use_rotator_downscale) {
   DisplayError error = kErrorNone;
 
   float scale_x = 1.0f;
diff --git a/sdm/libs/core/resource_default.h b/sdm/libs/core/resource_default.h
index a4549b0..5c81332 100644
--- a/sdm/libs/core/resource_default.h
+++ b/sdm/libs/core/resource_default.h
@@ -50,7 +50,7 @@
   virtual void Purge(Handle display_ctx);
   virtual DisplayError SetMaxMixerStages(Handle display_ctx, uint32_t max_mixer_stages);
   virtual DisplayError ValidateScaling(const LayerRect &crop, const LayerRect &dst,
-                                       bool rotate90, bool ubwc_tiled);
+                                       bool rotate90, bool ubwc_tiled, bool use_rotator_downscale);
   DisplayError ValidateCursorConfig(Handle display_ctx, const Layer& layer, bool is_top);
   DisplayError ValidateCursorPosition(Handle display_ctx, HWLayers *hw_layers, int x, int y);
 
@@ -84,7 +84,7 @@
 
   // todo: retrieve all these from kernel
   enum {
-    kMaxDecimationDownScaleRatio = 8,
+    kMaxDecimationDownScaleRatio = 16,
   };
 
   struct SourcePipe {
diff --git a/sdm/libs/hwc/hwc_display.cpp b/sdm/libs/hwc/hwc_display.cpp
index 29a35b2..57b1dbc 100644
--- a/sdm/libs/hwc/hwc_display.cpp
+++ b/sdm/libs/hwc/hwc_display.cpp
@@ -892,7 +892,7 @@
   return error;
 }
 
-DisplayError HWCDisplay:: ControlPartialUpdate(bool enable, uint32_t *pending) {
+DisplayError HWCDisplay::ControlPartialUpdate(bool enable, uint32_t *pending) {
   DisplayError error = kErrorNone;
 
   if (display_intf_) {
@@ -1253,13 +1253,25 @@
 void HWCDisplay::ApplyScanAdjustment(hwc_rect_t *display_frame) {
 }
 
-DisplayError HWCDisplay::SetColorSpace(const ColorSpace_t source, LayerColorSpace *target) {
+DisplayError HWCDisplay::SetCSC(ColorSpace_t source, LayerCSC *target) {
   switch (source) {
-  case ITU_R_601:      *target = kLimitedRange601;   break;
-  case ITU_R_601_FR:   *target = kFullRange601;      break;
-  case ITU_R_709:      *target = kLimitedRange709;   break;
+  case ITU_R_601:       *target = kCSCLimitedRange601;   break;
+  case ITU_R_601_FR:    *target = kCSCFullRange601;      break;
+  case ITU_R_709:       *target = kCSCLimitedRange709;   break;
   default:
-    DLOGE("Unsupported Color Space: %d", source);
+    DLOGE("Unsupported CSC: %d", source);
+    return kErrorNotSupported;
+  }
+
+  return kErrorNone;
+}
+
+DisplayError HWCDisplay::SetIGC(IGC_t source, LayerIGC *target) {
+  switch (source) {
+  case IGC_NotSpecified:    *target = kIGCNotSpecified; break;
+  case IGC_sRGB:            *target = kIGCsRGB;   break;
+  default:
+    DLOGE("Unsupported IGC: %d", source);
     return kErrorNotSupported;
   }
 
@@ -1275,7 +1287,13 @@
   }
 
   if (meta_data->operation & UPDATE_COLOR_SPACE) {
-    if (SetColorSpace(meta_data->colorSpace, &layer->color_space) != kErrorNone) {
+    if (SetCSC(meta_data->colorSpace, &layer->csc) != kErrorNone) {
+      return kErrorNotSupported;
+    }
+  }
+
+  if (meta_data->operation & SET_IGC) {
+    if (SetIGC(meta_data->igc, &layer->igc) != kErrorNone) {
       return kErrorNotSupported;
     }
   }
diff --git a/sdm/libs/hwc/hwc_display.h b/sdm/libs/hwc/hwc_display.h
index 0aab57b..49e03a6 100644
--- a/sdm/libs/hwc/hwc_display.h
+++ b/sdm/libs/hwc/hwc_display.h
@@ -144,7 +144,8 @@
   void CloseAcquireFences(hwc_display_contents_1_t *content_list);
   uint32_t RoundToStandardFPS(uint32_t fps);
   virtual void ApplyScanAdjustment(hwc_rect_t *display_frame);
-  DisplayError SetColorSpace(const ColorSpace_t source, LayerColorSpace *target);
+  DisplayError SetCSC(ColorSpace_t source, LayerCSC *target);
+  DisplayError SetIGC(IGC_t source, LayerIGC *target);
   DisplayError SetMetaData(const private_handle_t *pvt_handle, Layer *layer);
   bool NeedsFrameBufferRefresh(hwc_display_contents_1_t *content_list);
   void CacheLayerStackInfo(hwc_display_contents_1_t *content_list);